package com.cc.data_explore.gui.tab;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cc.data_explore.gui.helper.StageHelper;
import com.cc.data_explore.logic.data.AnalysisTableData;
import com.cc.data_explore.logic.mybatis.DbHelper;
import com.cc.data_explore.logic.mybatis.mapper.sub.FileDataMapper;
import com.cc.data_explore.logic.mybatis.mapper.sub.FileInfoMapper;
import com.cc.data_explore.logic.mybatis.mapper.sub.TableConfigMapper;
import com.cc.data_explore.logic.mybatis.model.FileData;
import com.cc.data_explore.logic.mybatis.model.FileInfo;
import com.cc.data_explore.logic.mybatis.model.TableConfig;
import de.saxsys.mvvmfx.ViewModel;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.RandomUtil;
import org.dromara.hutool.json.JSONUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * PrimaryDialogView
 *
 * @author aa
 * @version 1.0
 * @since 2025/4/1
 */
public class CreateTableDialogViewModel implements ViewModel {

    private final StringProperty targetTableNameText = new SimpleStringProperty();
    private final StringProperty headLineText = new SimpleStringProperty();
    @Getter
    private final ObservableList<CreateTableDialogData> items = FXCollections.observableArrayList();

    private static final Pattern PATTERN = Pattern.compile("^\\d.*");
    @Getter
    @Setter
    private Long sheetId;

    public void initialize() {
        System.out.println("MainViewModelinitialize");
    }

    public void initData(Long sheetId) {
        setSheetId(sheetId);
        SqlSessionFactory sqlSessionFactory = DbHelper.getInstance().getSqlSessionFactory();
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            FileInfoMapper infoMapper = sqlSession.getMapper(FileInfoMapper.class);
            FileInfo fileInfo = infoMapper.selectById(sheetId);
            targetTableNameText.set(fileInfo.getFileName());
        }
    }

    public void setPrimaryDialogViewModel() {
        String headLine = getHeadLineText();
        if (StrUtil.isEmpty(headLine)) {
            return;
        }
        SqlSessionFactory sqlSessionFactory = DbHelper.getInstance().getSqlSessionFactory();
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            FileDataMapper mapper = sqlSession.getMapper(FileDataMapper.class);
            String limit = StrUtil.format("limit {} offset {}", headLine, headLine);
            FileData fileData = mapper.selectOne(Wrappers.<FileData>lambdaQuery().eq(FileData::getSheetId, sheetId).last(limit));
            String colContent = fileData.getDataContent();
            Map<String, String> colMap = JSONUtil.parse(colContent).toBean(Map.class);
            items.clear();
            colMap.forEach((key, value) -> items.add(new CreateTableDialogData(value, value, FiledTypeEnum.TEXT, Boolean.TRUE)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public String getTargetTableNameText() {
        return targetTableNameText.get();
    }

    public StringProperty targetTableNameTextProperty() {
        return targetTableNameText;
    }

    public String getHeadLineText() {
        return headLineText.get();
    }

    public StringProperty headLineTextProperty() {
        return headLineText;
    }

    public boolean completeBtnFun() {
        String headLine = getHeadLineText();
        String targetTableName = getTargetTableNameText();
        if (items.isEmpty()) {
            return false;
        }
        String tableNameEn = RandomUtil.randomString(9);
        Matcher matcher = PATTERN.matcher(tableNameEn);
        boolean isMatch = matcher.matches();
        if (isMatch) {
            tableNameEn = "A" + tableNameEn;
        }
        StringBuilder
                builder = new StringBuilder("CREATE TABLE ").append(tableNameEn).append(" ( id INTEGER NOT NULL,");
        List<AnalysisTableData> analysisTableDataList = new ArrayList<>();
        AtomicInteger count = new AtomicInteger();
        items.stream().filter(CreateTableDialogData::isSelected).forEach(item -> {
            String fieldNameEn = RandomUtil.randomString(8);
            Matcher fieldMatcher = PATTERN.matcher(fieldNameEn);
            boolean isFieldMatch = fieldMatcher.matches();
            if (isFieldMatch) {
                fieldNameEn = "A" + fieldNameEn + count.getAndIncrement();
            } else {
                fieldNameEn = fieldNameEn + count.getAndIncrement();
            }
            builder.append(fieldNameEn).append(" ").append(item.getFiledType().name()).append(" NULL,");
            AnalysisTableData analysisTableData = new AnalysisTableData();
            analysisTableData.setTableFieldEn(fieldNameEn);
            analysisTableData.setTableFieldZh(item.getTargetField());
            analysisTableData.setFiledType(item.getFiledType());
            analysisTableDataList.add(analysisTableData);
        });
        builder.append("dataContent").append(" TEXT ").append("NULL,");
        builder.append("CONSTRAINT TABLE_CONFIG_PK PRIMARY KEY (id) );");
        TableConfig tableConfig = new TableConfig();
        tableConfig.setTableName(targetTableName);
        tableConfig.setHeadLine(Integer.parseInt(headLine));
        tableConfig.setTableNameEn(tableNameEn);
        tableConfig.setHeadList(JSONUtil.toJsonStr(analysisTableDataList));
        SqlSessionFactory sqlSessionFactory = DbHelper.getInstance().getSqlSessionFactory();
        try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
            TableConfigMapper mapper = sqlSession.getMapper(TableConfigMapper.class);
            mapper.insert(tableConfig);
            mapper.createAnalysisTable(builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        Stage stage = StageHelper.getStage("创建分析表");
        if (stage != null) {
            stage.close();
            StageHelper.removeStage("创建分析表");
        }
        return true;
    }
}
